﻿using System;
using System.Windows.Forms;
using System.IO;
using System.Reflection;

namespace BizElements.Generator
{
    public partial class MainFrm : Form
    {
        ProjectController projController = new ProjectController();
        OnLoadArgs onLoadArgs;

        public MainFrm()
        {
            InitializeComponent();
            HideAllProjectControls();
            SwitchSaveAndCloseCommands();
        }

        public MainFrm(OnLoadArgs onLoadArgs)
            : this()
        {
            this.onLoadArgs = onLoadArgs;
        }

        private void HideAllProjectControls()
        {
            this.uiDbProject.Visible = false;
            this.uiDotNetProject.Visible = false;
        }

        private void SwitchSaveAndCloseCommands()
        {
            bool existsProjec = (this.projController.ProjectSettings != null);
            this.uiMenuSave.Enabled = this.uiMenuSaveAs.Enabled = this.uiMenuCloseProject.Enabled = existsProjec;
        }

        private void MainFrm_Load(object sender, EventArgs e)
        {            
            if (this.onLoadArgs != null)
            {
                InitProject(this.onLoadArgs.Project, this.onLoadArgs.ProjectFile);
                this.onLoadArgs = null;
            }

            this.Text = this.projController.GetTitleBarText();            
        }

        private IProjectUserControl GetProjectUserControl(BizElementsSettingsType projectType)
        {
            switch (projectType)
            { 
                case BizElementsSettingsType.OrmProject:
                    return this.uiDbProject;
                case BizElementsSettingsType.DotNetProject:
                    return this.uiDotNetProject;
                default:
                    throw new ArgumentException("Unsupported project type: " + projectType.ToString() + ".");
            }
        }        

        private void uiMenuNewDbProj_Click(object sender, EventArgs e)
        {
            InitProject(ProjectController.NewOrmProject(), null);
        }

        private void uiMenuNewDotNetProj_Click(object sender, EventArgs e)
        {
            InitProject(ProjectController.NewDotNetProject(), null);
        }

        private void uiMenuNewOrmAndBlProj_Click(object sender, EventArgs e)
        {
            InitProject(ProjectController.NewOrmAndBlProject(), null);
        }

        private void uiMenuNewOrmMinProj_Click(object sender, EventArgs e)
        {
            InitProject(ProjectController.NewOrmMinimumProject(), null);
        }

        private void uiMenuNewAspNetProj_Click(object sender, EventArgs e)
        {
            InitProject(ProjectController.NewAspNetProject(), null);
        }

        private void InitProject(BizElementsSettings project, string projectFile)
        {
            CloseCurrentProject();
            this.projController.ProjectSettings = project;
            this.projController.ProjectFile = projectFile;
            IProjectUserControl ucProj = GetProjectUserControl(this.projController.ProjectSettings.SettingsType);
            this.projController.InitializeControl(ucProj);
            SwitchSaveAndCloseCommands();
            this.Text = this.projController.GetTitleBarText();
        }

        private void uiMenuOpen_Click(object sender, EventArgs e)
        {
            OpenProjectFile();
        }

        private void OpenProjectFile()
        {
            DialogResult answer = this.uiMenuOpenFile.ShowDialog();
            if (answer == DialogResult.OK)
            {
                string projectFile = this.uiMenuOpenFile.FileName;
                try
                {
                    var project = BizElementsSettings.LoadFromFile(projectFile);
                    InitProject(project, projectFile);
                }
                catch (Exception e)
                {
                    string errmsg = string.Format(Messages.DbProjectFrm_CannotReadFileUsingDfltSettingsFormat, projectFile);
                    errmsg += Environment.NewLine + Environment.NewLine + "------------------------------------------------------------" + Environment.NewLine + Environment.NewLine;
                    errmsg += e.ToString();

                    MessageBox.Show(errmsg, Messages.Error, MessageBoxButtons.OK, MessageBoxIcon.Error);
                    CloseCurrentProject();
                }
            }
        }

        private void uiMenuSave_Click(object sender, EventArgs e)
        {
            SaveProject();
        }

        private void uiMenuSaveAs_Click(object sender, EventArgs e)
        {
            ChooseFileAndSaveProject();
        }

        private void SaveProject()
        {            
            if (this.projController.ProjectFile == null)
                ChooseFileAndSaveProject();
            else
                SaveProject(this.projController.ProjectFile);
        }

        private void ChooseFileAndSaveProject()
        {
            DialogResult answer = this.uiMenuSaveFile.ShowDialog();
            if (answer == DialogResult.OK)
                SaveProject(this.uiMenuSaveFile.FileName);
        }

        private void SaveProject(string projectFile)
        {
            this.projController.WriteProjectSettings();
            try
            {
                this.projController.ProjectSettings.SaveToFile(projectFile);
                this.projController.ProjectFile = projectFile;
                this.Text = this.projController.GetTitleBarText();
            }
            catch (Exception e)
            {
                string errmsg = string.Format(Messages.DbProjectFrm_CannotSaveProjectFileX, projectFile) + Environment.NewLine + e.ToString();
                MessageBox.Show(errmsg, Messages.Error, MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void MainFrm_FormClosing(object sender, FormClosingEventArgs e)
        {
            this.projController.WriteProjectSettings();
            if ((this.projController.ProjectSettings != null) && this.projController.ProjectSettings.HasChanges)
                SaveProject();
        }

        private void uiMenuCloseProject_Click(object sender, EventArgs e)
        {
            CloseCurrentProject();
        }

        private void CloseCurrentProject()
        {
            this.projController.WriteProjectSettings();
            if ((this.projController.ProjectSettings != null) && this.projController.ProjectSettings.HasChanges)
                SaveProject();

            this.projController.ProjectFile = null;
            this.projController.ProjectSettings = null;
            this.projController.ProjectUserControl = null;

            this.Text = this.projController.GetTitleBarText();
            HideAllProjectControls();
            SwitchSaveAndCloseCommands();
        }

        private void uiDbProject_WriteProjectSettingsDemanded(object sender, EventArgs e)
        {
            this.projController.WriteProjectSettings();
        }

        private void uiDotNetProject_WriteProjectSettingsDemanded(object sender, EventArgs e)
        {
            this.projController.WriteProjectSettings();
        }

        public class OnLoadArgs
        {
            public BizElementsSettings Project { get; set; }
            public string ProjectFile { get; set; }
            public string ErrorMessage { get; set; }
        }

        private void uiMenuHelpManual_Click(object sender, EventArgs e)
        {
            Help.ShowHelp(this, "Elements - Framework Reference.chm");
        }

        private void uiMenuHelpTemplateEngineReference_Click(object sender, EventArgs e)
        {
            Help.ShowHelp(this, "Elements - Template Engine and Generator Reference.chm");
        }

        private void uiMenuHelpAbout_Click(object sender, EventArgs e)
        {
            AboutFrm about = new AboutFrm();
            about.ShowDialog();
        }                      
    }    
}
